package com.xuecheng.media.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.MediaConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.*;
import com.xuecheng.commons.model.vo.MediaVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.VodUploadVo;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.media.config.VodTemplate;
import com.xuecheng.media.domain.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-09-18
 */
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {

    @Autowired
    VodTemplate vodTemplate;
    @Override
    public ResponseResult getTokenForVideo(VodUploadDto dto) throws ClientException {
        //参数非法检验
        if ((StrUtil.isEmpty(dto.getFileName())||StrUtil.isEmpty(dto.getTitle()))) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //获取上传凭证和地址
        CreateUploadVideoResponse videoResponse = vodTemplate.CreateUploadVideo(dto.getTitle(), dto.getFileName());
        String uploadAuth = videoResponse.getUploadAuth();
        String uploadAddress = videoResponse.getUploadAddress();
        //获取请求ID
        String requestId = videoResponse.getRequestId();
        //获取视频ID
        String videoId = videoResponse.getVideoId();
        //封装返回数据
        VodUploadVo vo = new VodUploadVo();
        vo.setRequestId(requestId);
        vo.setUploadAddress(uploadAddress);
        vo.setUploadAuth(uploadAuth);
        vo.setVideoId(videoId);
        vo.setUserId(AuthInfoHolder.getUserId().toString());
        //返回数据
        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult refreshToken(String videoId) throws ClientException {
        //1.参数非法检验
        if ((StrUtil.isEmpty(videoId))) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //2.刷新凭证
        RefreshUploadVideoResponse response = vodTemplate.RefreshUploadVideo(videoId);
        VodUploadVo vo = BeanHelper.copyProperties(response, VodUploadVo.class);
        vo.setUserId(AuthInfoHolder.getUserId().toString());

        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult saveMedia(MediaDto dto) throws ClientException {
        //1.转实体
        Media media = BeanHelper.copyProperties(dto, Media.class);
        //2.查询媒资时长+播放地址
        //2-1.查询时长
        GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
        String duration = response.getVideoBase().getDuration();
        //2-2.查询播放地址
        String playURL = response.getPlayInfoList().get(0).getPlayURL();
        //3.补充信息
        //3-1.时长 毫秒转成分钟
        Float f = Float.parseFloat(duration);
        Duration time = Duration.ofMinutes(f.longValue());
        LocalTime timeLength = LocalTime.MIN.plus(time);
        media.setTimelength(timeLength.toString());
        //3-2.播放地址
        media.setUrl(playURL);
        //3-3.上传人
        media.setUrl(AuthInfoHolder.getUserId().toString());
        //3-4上传时间
        media.setCreateDate(new Date());
        //3-5 审核状态
        media.setAuditStatus(MediaConstants.AUDIT_UNPAST_STATUS);
        //4.保存数据
        this.save(media);


        return ResponseResult.okResult();
    }

    /**
     * 分页查询
     * @param pageRequest 封装pageNo、pageSize
     * @param dto
     * @return
     */
    @Override
    public ResponseResult selectByPage(PageRequest pageRequest, MediaQueryDto dto) {
        Integer pageNo = pageRequest.getPageNo();
        Integer pageSize = pageRequest.getPageSize();
        //1.构建分页
        System.out.println(pageNo);

        Page<Media> page = new Page<>(pageNo, pageSize);
        //2.构建条件
        LambdaQueryWrapper<Media> qw = new LambdaQueryWrapper<>();
        //2-1.媒资名称
        qw.like(StrUtil.isNotEmpty(dto.getFilename()),Media::getFilename,dto.getFilename());
        //2-2.媒资类型
        qw.eq(StrUtil.isNotEmpty(dto.getType()),Media::getType,dto.getType());
        //2-3.审核状态
        qw.eq(StrUtil.isNotEmpty(dto.getAuditStatus()),Media::getAuditStatus,dto.getAuditStatus());
        //3.执行查询
        page = this.page(page, qw);
        //4.转vo
        List<Media> mediaList = page.getRecords();
        List<MediaVo> voList = BeanHelper.copyWithCollection(mediaList, MediaVo.class);
        //5.返回分页数据

        return PageResponseResult.okResult(page.getTotal(),voList);
    }

    @Override
    public ResponseResult selectByMediaId(String mediaId) throws ClientException {
        Media media = this.getById(mediaId);
        //1.取出播放地址，判断是否超时，没有则返回地址

        GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
        String playURL = response.getPlayInfoList().get(0).getPlayURL();
        //2-2.重置到media
        media.setUrl(playURL);




        //3.返回播放地址
        return ResponseResult.okResult(playURL);
    }

    @Override
    public ResponseResult deleteMediaById(String mediaId) throws ClientException {
        Media media = this.getById(mediaId);
        //查询状态
        String auditStatus = media.getAuditStatus();
        //已审核不能删除
        if ((StrUtil.equals(auditStatus,MediaConstants.AUDIT_PASTED_STATUS))) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //2.删除
        //2-1.删除阿里云里的数据
        vodTemplate.deleteVideo(media.getFileId());
        //2-2.删除本地的媒资数据
        this.removeById(mediaId);
        return ResponseResult.okResult();
    }



    @Override
    public ResponseResult auditMedia(MediaAuditDto dto) {
        //1.构建媒资对象
        Media media = this.getById(dto.getId());
        //2.设置状态
        media.setAuditStatus(dto.getAuditStatus());
        //3.更新数据库
        this.updateById(media);
        //提交
        return ResponseResult.okResult();
    }
}
